﻿#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    baseUrl=URL_BASE;
    isStatusIdle=true;
    form=WF_NORMAL;

    itemModel=new QStandardItemModel(this);
    view=new ItemView(this);
    ui->treeView->setModel(itemModel);
    ui->treeView->setEditTriggers(QTreeView::NoEditTriggers);

    makeupFlashdb();
    createTray();
    createMenu();
    startReceiver();
    updateView();
    move(100,100);
}

Dialog::~Dialog()
{
    stopReceiver();
    delete ui;
}

void Dialog::startReceiver()
{
    receiver=new BaseRestReceiver;
    connect(this,&Dialog::get,
            receiver,&BaseRestReceiver::httpGet);
    connect(this,&Dialog::post,
            receiver,&BaseRestReceiver::httpPost);

    connect(receiver,&BaseRestReceiver::receivedObject,
            this,&Dialog::onReceivedObject);
    connect(receiver,&BaseRestReceiver::networkError,
            this,&Dialog::onError);
    connect(&recvThread,&QThread::finished,
            receiver,&QObject::deleteLater);
    receiver->moveToThread(&recvThread);
    recvThread.start();
}

void Dialog::stopReceiver()
{
    recvThread.quit();
    recvThread.wait();
}

void Dialog::makeupFlashdb()
{
    if(db.isValid())
        db.item_createTable();
    else
        qDebug() << "CREATE DB FAILURE";
}

void Dialog::onError()
{
    form=WF_EXCEPTION;
    ui->status->setText(QStringLiteral("服务器离线"));
}

void Dialog::onReceivedObject(const QJsonObject &object)
{
    if(!object.contains("entry"))
        return;

    if(object.value("entry").toString() != T_QUICKREPLY)
        return;

    if(object.contains("categories"))
    {
        QJsonArray array=object.value("categories").toArray();
        processCategory(array);
    }
    else if(object.contains("detail"))
    {
        QJsonArray array=object.value("detail").toArray();
        processDetail(array);
    }
}

void Dialog::processCategory(const QJsonArray &array)
{
    if(array.isEmpty())
        return;

    for(int i=0;i<array.size();i++)
    {
        QString row=array.at(i).toString();
        itemModel->appendRow(new QStandardItem(row));
    }

    if(itemModel->rowCount() > 0)
        showStatus(QStringLiteral("云端数据已同步"),6000);
    // ui->treeView->resizeColumnToContents(0);
}

void Dialog::processDetail(const QJsonArray &array)
{
    if(array.isEmpty())
        return;

    if(form == WF_NORMAL)
    {
        if(selectCategory.isEmpty())
            return;

        QModelIndex index=ui->treeView->currentIndex();
        if(!index.isValid())
            return;

        QStandardItem *item=itemModel->item(index.row());
        for(int i=0;i<array.size();i++)
        {
            QJsonObject obj=array.at(i).toObject();
            QString label=obj.value("label").toString();
            QString detail=obj.value("detail").toString();
            if(label.isEmpty() || detail.isEmpty())
                continue;

            db.item_insert(selectCategory,label,detail);
            item->appendRow(new QStandardItem(label));
        }
        ui->treeView->expand(index);
    }

    else if(form == WF_SEARCH)
    {
        for(int i=0;i<array.size();i++)
        {
            QJsonObject obj=array.at(i).toObject();
            QString category=obj.value("category").toString();
            QString label=obj.value("label").toString();
            QString detail=obj.value("detail").toString();
            if(category.isEmpty() || label.isEmpty())
                continue;

            QList<QStandardItem *> row;
            row.append(new QStandardItem(category));
            row.append(new QStandardItem(label));
            itemModel->appendRow(row);

            QString key=category + label;
            resultCache.insert(key,detail);
        }
        ui->input->clear();
    }
}

void Dialog::createTray()
{
    tray_Menu=new QMenu(this);
    tray_Menu->addAction(QStringLiteral("退出"),QApplication::quit);
    tray=new QSystemTrayIcon(QIcon(":/quick.ico"),this);
    tray->setContextMenu(tray_Menu);
    tray->setToolTip(QString::number(SP_VER) + QStringLiteral(" - 快捷回复运行中"));

    connect(tray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this,SLOT(trayActivated(QSystemTrayIcon::ActivationReason))
            );
    tray->show();
}

void Dialog::trayActivated(QSystemTrayIcon::ActivationReason reason)
{
    if(reason == QSystemTrayIcon::DoubleClick)
    {
        if(this->isVisible())
            this->hide();
        else
            this->show();
    }
}

void Dialog::updateView()
{
    if(form == WF_EXCEPTION)
        return;

    form=WF_NORMAL;
    if(itemModel->rowCount() != 0)
        itemModel->clear();

    itemModel->setHorizontalHeaderItem(0,new QStandardItem(QStringLiteral("类别")));
    if(!db.isEmpty())
    {
        QStringList items=db.item_getCategories();
        foreach (QString item, items) {
            itemModel->appendRow(new QStandardItem(item));
        }
    }
    else
        emit get(baseUrl + "get_categories");
}

void Dialog::createMenu()
{
    menu=new QMenu(this);
    updateMenu();
}

void Dialog::contextMenuEvent(QContextMenuEvent *)
{
    if(menu != nullptr)
        menu->exec(QCursor::pos());
}

void Dialog::updateMenu()
{
    if(!menu->isEmpty())
    {
        menu->disconnect();
        menu->clear();
    }

    menu->addAction(QStringLiteral("更新视图"),this,&Dialog::updateView);
    QMenu *option=menu->addMenu(QStringLiteral("选项"));
    option->addAction(QStringLiteral("删除图片文件"),this,&Dialog::removePicture);
    option->addSeparator();
    option->addAction(QStringLiteral("同步云端数据"),this,&Dialog::syncDataScource);
    menu->addAction(QStringLiteral("全部折叠"),this,&Dialog::collapseAll);
}

void Dialog::syncDataScource()
{
    if(!db.isEmpty())
        db.clear();

    if(itemModel->rowCount() != 0)
        itemModel->clear();

    itemModel->setHorizontalHeaderItem(0,new QStandardItem(QStringLiteral("类别")));
    emit get(baseUrl + "get_categories");
}

void Dialog::collapseAll()
{
    ui->treeView->collapseAll();
}

void Dialog::showItemView(const QString &label,const QString &detail)
{
    view->move(this->x() + this->width() + 10,this->y());
    view->display(label,detail);

    if(!view->isVisible())
        view->show();
}

void Dialog::timerEvent(QTimerEvent *event)
{
    int id=event->timerId();
    if(id == cleanTimer)
    {
        ui->status->clear();
        killTimer(cleanTimer);
        isStatusIdle=true;
    }
}

void Dialog::on_treeView_clicked(const QModelIndex &index)
{
    if(!index.isValid())
        return;

    if(form == WF_NORMAL)
    {
        QModelIndex parentIndex=index.parent();
        if(parentIndex.isValid())    // 子节点
        {
            selectCategory=parentIndex.data().toString();
            selectLabel=index.data().toString();
            selectDetail=db.item_getDetail(selectCategory,selectLabel);
        }
        else {  // 根节点
            selectCategory=index.data().toString();
            return;
        }
    }
    else if(form == WF_SEARCH)
    {
        selectCategory=index.sibling(index.row(),0).data().toString();
        selectLabel=index.sibling(index.row(),1).data().toString();
        QString key=selectCategory + selectLabel;
        selectDetail=resultCache.value(key);
    }

    if(selectDetail.isEmpty())
        return;

    showItemView(selectLabel,selectDetail);
}

void Dialog::on_treeView_doubleClicked(const QModelIndex &index)
{
    // 根节点
    if(!index.parent().isValid() && form == WF_NORMAL)
    {
        if(selectCategory.isEmpty())
            return;

        if(!itemModel->item(index.row())->hasChildren())
        {
            ui->treeView->collapseAll();
            emit get(baseUrl + "by_category/" + selectCategory);
        }
    }
}

void Dialog::showStatus(const QString &message,int interval)
{
    ui->status->setText(message);
    if(!isStatusIdle)
        killTimer(cleanTimer);
    cleanTimer=startTimer(interval);
}

void Dialog::removePicture()
{
    if(form != WF_NORMAL)
        return;

    if(selectDetail.isEmpty())
        return;

    if(selectDetail.startsWith(PRE_CDN))
    {
        QString fileName=selectDetail;
        fileName=fileName.remove(PRE_CDN);
        QString filePath=P_FHS_CACHE + fileName;
        if(QFile::exists(filePath))
        {
            if(QFile::remove(filePath))
                showStatus(QStringLiteral("图片已删除"));
            else
                showStatus(QStringLiteral("删除失败！"),6000);
        }
    }
}

void Dialog::on_input_returnPressed()
{
    QString keyword=ui->input->text().trimmed();
    if(keyword.isEmpty())
        return;

    form=WF_SEARCH;
    if(itemModel->rowCount() != 0)
        itemModel->clear();

    if(!resultCache.isEmpty())
        resultCache.clear();

    itemModel->setHorizontalHeaderLabels(QStringList() << QStringLiteral("类别") << keyword);
    emit get(baseUrl + "search/" + keyword);

    /*
    QList<QStringList> items=db.item_getItems(keyword);
    foreach (QStringList item, items) {
        QList<QStandardItem *> row;
        row.append(new QStandardItem(item.first()));
        row.append(new QStandardItem(item.last()));
        itemModel->appendRow(row);
    }
    */
}
